package com.markerhub.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.markerhub.common.lang.Result;
import com.markerhub.config.SmsConfig;
import com.markerhub.config.SmsLengthEnum;
import com.markerhub.config.SmsResponseCodeEnum;
import com.markerhub.service.ISmsService;
import com.markerhub.util.RedisUtil;
import com.markerhub.util.SmsCodeUtil;
import com.markerhub.util.SmsUtil;
import com.tencentcloudapi.sms.v20190711.models.SendStatus;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @Author by MaXiaofeng
 * @Description 短信业务实现类
 * @Date 2022/2/13 16:56
 * @Version 1.0.0
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class SmsServiceImpl implements ISmsService {
    @Autowired
    private SmsConfig smsConfig;

    /**
     * 腾讯云短信模板id-短信验证码
     */
    @Value("${sms-config.templateIds.code}")
    private String templateIdCode;

    @Override
    public Result sendSmsByCheckCode(String Phone, int cabinet_doorNum) {
        JSONObject jsonObject = JSON.parseObject(Phone);
        String phone = (String) jsonObject.get("phone");
        // redis缓存的键
        final String smsKey = SmsCodeUtil.createSmsCacheKey(smsConfig.getPhonePrefix(), phone, "wxUser_sign");
        //下发手机号码，采用 e.164 标准，+[国家或地区码][手机号]  示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号
        String[] phoneNumbers = {"+86" + phone};
        //模板参数: 若无模板参数，则设置为空（第一个参数为随机验证码，第二个参数为有效时间）
        final String smsRandomCode = SmsCodeUtil.createSmsRandomCode(SmsLengthEnum.SMS_LENGTH_4);
        String[] templateParams = {smsRandomCode, smsConfig.getExpireTime()}; //第一个参数：取餐码为随机生成的四位有效数字；第二个数有效时间为配置文件中定义的
        SendStatus[] sendStatuses = SmsUtil.sendSms(smsConfig, templateIdCode, templateParams, phoneNumbers);
        String resCode = sendStatuses[0].getCode();
        if (resCode.equals(SmsResponseCodeEnum.OK.getCode())) {
            // 返回ok，缓存
            RedisUtil.StringOps.setEx(smsKey, smsRandomCode, Long.parseLong(smsConfig.getExpireTime()), TimeUnit.MINUTES);
            return Result.success("发送短信成功");
        } else {
            log.error("【短信业务-发送失败】phone:" + phone + "errMsg:" + sendStatuses[0].getMessage());
            return Result.fail("【短信业务-发送失败】phone:" + phone + "errMsg:" + sendStatuses[0].getMessage());
        }
    }

    @Override
    public void verifyCode(String phone, String code) {
        // redis缓存的键
        final String smsKey = SmsCodeUtil.createSmsCacheKey(smsConfig.getPhonePrefix(), phone, "wxUser_sign");
        // 如果key存在（存在并且未过期）
        if (RedisUtil.KeyOps.hasKey(smsKey)) {
            String cacheCode = RedisUtil.StringOps.get(smsKey).toString();
            if (cacheCode.equals(code)) {
                //验证码正确
                //删除验证码缓存
                RedisUtil.KeyOps.delete(smsKey);
                log.info("【短信业务-微信小程序手机认证成功】phone：" + phone);
            } else {
                //验证码不正确
                log.error("【短信业务-微信小程序手机认证失败】验证码错误。phone：" + phone);
//                throw new BaseException(ResponseEnum.SMS_CODE_VERITY_FAIL);
            }
        } else {
            log.error("【短信业务-微信小程序手机认证失败】验证码失效。phone：" + phone);
//            throw new BaseException(ResponseEnum.SMS_CODE_EXPIRE);
        }
    }

    @Override
    public Result sendSmsByCabinetNum(String phone, int cabinet_doorNum) {
        // redis缓存的键
        final String smsKey = SmsCodeUtil.createSmsCacheKey(smsConfig.getPhonePrefix(), phone, "wxUser_sign");
        //下发手机号码，采用 e.164 标准，+[国家或地区码][手机号]  示例如：+8613711112222， 其中前面有一个+号 ，86为国家码，13711112222为手机号，最多不要超过200个手机号
        String[] phoneNumbers = {"+86" + phone};
        //模板参数: 若无模板参数，则设置为空（第一个参数为随机验证码，第二个参数为有效时间）
        final String smsRandomCode = SmsCodeUtil.createSmsRandomCode(SmsLengthEnum.SMS_LENGTH_4);
        /**
         * 第一个参数：手机号后四位；第二个数柜门号
         */
        String cabinetNum = String.valueOf(cabinet_doorNum);
        String[] templateParams = {phone.substring(phone.length() - 4, phone.length()), cabinetNum};
        SendStatus[] sendStatuses = SmsUtil.sendSms(smsConfig, templateIdCode, templateParams, phoneNumbers);
        String resCode = sendStatuses[0].getCode();
        if (resCode.equals(SmsResponseCodeEnum.OK.getCode())) {
            // 返回ok，缓存
            RedisUtil.StringOps.setEx(smsKey, smsRandomCode, Long.parseLong(smsConfig.getExpireTime()), TimeUnit.MINUTES);
            return Result.success("发送短信成功");
        } else {
            log.error("【短信业务-发送失败】phone:" + phone + "errMsg:" + sendStatuses[0].getMessage());
            return Result.fail("【短信业务-发送失败】phone:" + phone + "errMsg:" + sendStatuses[0].getMessage());
        }
    }
}
